package asteroids.model.programs.parsing;


import java.util.List;
import asteroids.model.programs.parsing.expressions.*;
import asteroids.model.programs.parsing.types.*;
import asteroids.model.programs.parsing.statements.*;

public class Factory<E, S ,T> implements ProgramFactory<Expression, Statement, Type> {
	public Factory() {
	
	}

	@Override
	public Expression createDoubleLiteral(int line, int column, double d) {
		DoubleLiteral dt = new DoubleLiteral(d);
		return new ConstantExpr(dt,line, column);
	}

	@Override
	public Expression createBooleanLiteral(int line, int column, boolean b) {
		BooleanLiteral bt = new BooleanLiteral(b);
		return new ConstantExpr(bt,line, column);
	}

	@Override
	public Expression createAnd(int line, int column, Expression e1, Expression e2) {		
		return new AndExpr(e1,e2,line, column);
	}

	@Override
	public Expression createOr(int line, int column, Expression e1, Expression e2) {
		return new OrExpr(e1,e2,line, column);
	}

	@Override
	public Expression createNot(int line, int column, Expression e) {
		return new NegatedExpr(e,line, column);
	}

	@Override
	public Expression createNull(int line, int column) {
		return new NullExpr(line, column);
	}

	@Override
	public Expression createSelf(int line, int column) {
		return new SelfExpr(line, column);
	}

	@Override
	public Expression createGetX(int line, int column, Expression e) {
		return new GetXExpr(e,line, column);
	}

	@Override
	public Expression createGetY(int line, int column, Expression e) {
		return new GetYExpr(e,line, column);
	}

	@Override
	public Expression createGetVX(int line, int column, Expression e) {
		return new GetVelXExpr(e,line, column);
	}

	@Override
	public Expression createGetVY(int line, int column, Expression e) {
		return new GetVelYExpr(e,line, column);
	}

	@Override
	public Expression createGetRadius(int line, int column, Expression e) {
		return new GetRadiusExpr(e,line, column);
	}

	@Override
	public Expression createVariable(int line, int column, String name) {
		return new VariableExpr(name,line, column);
	}

	@Override
	public Expression createLessThan(int line, int column, Expression e1, Expression e2) {
		return new SmallerThan(e1,e2,line, column);
	}

	@Override
	public Expression createGreaterThan(int line, int column, Expression e1, Expression e2) {
		return new SmallerThanOrEqual(e2,e1,line, column);
	}

	@Override
	public Expression createLessThanOrEqualTo(int line, int column, Expression e1, Expression e2) {
		return new SmallerThanOrEqual(e1,e2,line, column);
	}

	@Override
	public Expression createGreaterThanOrEqualTo(int line, int column, Expression e1, Expression e2) {
		return new SmallerThan(e2,e1,line, column);
	}

	@Override
	public Expression createEquality(int line, int column, Expression e1, Expression e2) {
		return new EqualExpr(e1,e2,line, column);
	}

	@Override
	public Expression createInequality(int line, int column, Expression e1, Expression e2) {
		return new NegatedExpr (new EqualExpr(e1,e2,line, column),line, column);
	}

	@Override
	public Expression createAdd(int line, int column, Expression e1, Expression e2) {
		return new AddExpr(e1,e2,line, column);
	}

	@Override
	public Expression createSubtraction(int line, int column, Expression e1, Expression e2) {
		return new SubtractExpr(e1,e2,line, column);
	}

	@Override
	public Expression createMul(int line, int column, Expression e1, Expression e2) {
		return new MultiplyExpr(e1,e2,line, column);
	}

	@Override
	public Expression createDivision(int line, int column, Expression e1, Expression e2) {
		return new DivideExpr(e1,e2,line, column);
	}
	
	@Override
	public Expression createSqrt(int line, int column, Expression e) {
		return new SqrtExpr(e,line, column);
	}

	@Override
	public Expression createGetDirection(int line, int column) {
		return new getDirectionExpr(line, column);

	}

	@Override
	public Expression createSin(int line, int column, Expression e) {
		return new SinExpr(e,line, column);
	}

	@Override
	public Expression createCos(int line, int column, Expression e) {
		return new CosExpr(e,line, column);
	}

	@Override
	public Statement createEnableThruster(int line, int column) {
		return new Thrust(true,line, column);
	}

	@Override
	public Statement createDisableThruster(int line, int column) {
		return new Thrust(false,line, column);
	}

	@Override
	public Statement createFire(int line, int column) {
		return new Fire(line, column);
	}

	@Override
	public Statement createTurn(int line, int column, Expression angle) {		

			return new Turn(angle,line, column);
	
	}

	@Override
	public Statement createAssignment(int line, int column, String variable, Expression rhs) {
		return new Assignment(variable, rhs,line, column);
	}

	@Override
	public Statement createIf(int line, int column, Expression condition, Statement then, Statement otherwise) {
		return new IfStatement(condition,then,otherwise,line, column);
	}

	@Override
	public Statement createWhile(int line, int column, Expression condition, Statement body) {
		return new WhileStatement(condition,body,line, column);
	}

	@Override
	public Statement createForeach(int line, int column,
			asteroids.model.programs.parsing.ProgramFactory.ForeachType type,
			String variableName, Statement body) {
		return new ForeachStatement(type,variableName,body,line, column);
	}

	@Override
	public Statement createSkip(int line, int column) {
		return new Skip(line, column);
	}

	@Override
	public Statement createSequence(int line, int column, List<Statement> statements) {
		return new Sequence(statements,line, column);
	}

	@Override
	public Statement createPrint(int line, int column, Expression e) {	
		return new Print(e,line, column);
	}

	@Override
	public Type createDoubleType() {
		Type newDouble = new DoubleLiteral(0.0);
		return newDouble;
	}

	@Override
	public Type createBooleanType() {
		Type newBoolean = new BooleanLiteral(false);
		return newBoolean;
	}

	@Override
	public Type createEntityType() {
		Type newEntity = new EntityLiteral(null);
		return newEntity;
	}

}
